package internal

import (
	"context"
	"log"
	"time"
)

const (
	MaxSize     = 5 * 1024 * 1024
	TempFileDir = "./temp"
)

type Download struct {
	downloadFilePath string // 下载文件存储路径
	aim              *Aim   // 下载文件详情
}

func NewDownload(url, downloadFilePath string) (*Download, error) {
	aim, err := NewAim(url)
	if err != nil {
		log.Fatal(err)
	}
	d := &Download{
		aim:              aim,
		downloadFilePath: downloadFilePath,
	}

	return d, nil
}

func (d *Download) Run() {
	if d.aim.fileSize <= 0 {
		log.Fatal("[*] Destination server does not support breakpoint download.")
	}
	// 检查下载存放文件，不存在就创建
	if err := CreatePath(d.downloadFilePath); err != nil {
		log.Fatal(err)
	}

	if d.aim.fileSize > MaxSize {
		d.thread()
	} else {
		d.single()
	}
}

// 多线程
func (d *Download) thread() {
	log.Println("多线程下载，线程数量：", GoroutineNum)
	NewThread(d, TempFileDir).Run()
}

// 单线程
func (d *Download) single() {
	log.Println("单线程下载")
	w := NewWriter(0, d.aim.fileSize, d.downloadFilePath+"/"+d.aim.fileName, make(chan int64), make(chan struct{}), d.aim)
	go w.store()

	ctx, cancel := context.WithCancel(context.Background())
	dLog := NewDownloadLog(ctx, d.aim.fileSize, 500*time.Millisecond)

	for {
		select {
		case <-w.quitSignal:
			cancel()
			return
		case num := <-w.writerNum:
			dLog.AddSchedule(num)
		}
	}
}
